package com.uduemc.biso.node.web.api.controller.noauthentication;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.utils.CryptoJava;
import com.uduemc.biso.node.core.entities.HRepertory;
import com.uduemc.biso.node.core.entities.SInformationTitle;
import com.uduemc.biso.node.core.entities.SPdtableTitle;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.web.api.service.HostService;
import com.uduemc.biso.node.web.api.service.InformationService;
import com.uduemc.biso.node.web.api.service.PdtableService;
import com.uduemc.biso.node.web.api.service.RepertoryService;
import com.uduemc.biso.node.web.api.service.SystemService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import cn.hutool.poi.excel.style.StyleUtil;

@RequestMapping("/api/download")
@Controller
public class ApiDownloadController {

	@Autowired
	private RepertoryService repertoryServiceImpl;

	@Autowired
	private GlobalProperties globalProperties;

	@Autowired
	private HostService hostServiceImpl;

	@Autowired
	private SystemService systemServiceImpl;

	@Autowired
	private InformationService informationServiceImpl;

	@Autowired
	private PdtableService pdtableServiceImpl;

	@GetMapping("/repertory/{hostsecret}/{secret}")
	public void repertory(@PathVariable("hostsecret") String hostsecret, @PathVariable("secret") String secret, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		if (secret.lastIndexOf(".") > 1) {
			secret = StrUtil.sub(secret, 0, secret.lastIndexOf("."));
		}
		String de = CryptoJava.de(secret);
		String hostDe = CryptoJava.de(hostsecret);
		int id = 0;
		int hostId = 0;
		if (de != null) {
			try {
				hostId = Integer.valueOf(hostDe);
				id = Integer.valueOf(de);
			} catch (NumberFormatException e) {
			}
		}
		if (id < 1 || hostId < 1) {
			return;
		}

		Host host = hostServiceImpl.getInfoById(hostId);
		if (host == null) {
			return;
		}

		HRepertory hRepertory = repertoryServiceImpl.getInfoByid(id);
		if (hRepertory == null || hRepertory.getHostId().longValue() != hostId) {
			return;
		}

		String uri = request.getRequestURI();
		String substring = uri.substring(uri.lastIndexOf(".") + 1);
		if (!substring.equals(hRepertory.getSuffix())) {
			return;
		}

		String basePath = globalProperties.getSite().getBasePath();
		String userPathByCode = SitePathUtil.getUserPathByCode(basePath, host.getRandomCode());

		// 资源图片完整路径
		String filefullpath = userPathByCode + "/" + hRepertory.getFilepath();
		if (!FileUtil.isFile(filefullpath)) {
			return;
		}

		// 下载
		try (InputStream inputStream = new FileInputStream(filefullpath); OutputStream outputStream = response.getOutputStream();) {
			String outFilename = hRepertory.getOriginalFilename();
			response.setHeader("Accept-Ranges", "bytes");
			response.setHeader("Content-Length", String.valueOf(hRepertory.getSize()));
//			response.setHeader("Content-type", "text/html;charset=gbk");
			response.setHeader("Content-Transfer-Encoding", "binary");
			response.setContentType("application/x-download");
			response.addHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode(outFilename));
			IOUtils.copy(inputStream, outputStream);
			outputStream.flush();
		}
	}

	@GetMapping("/information/excel-demo/{hostsecret}/{systemsecret}")
	public void informationExcelDemo(@PathVariable("hostsecret") String hostsecret, @PathVariable("systemsecret") String systemsecret,
			HttpServletResponse response) throws Exception {
		String hostDe = CryptoJava.de(hostsecret);
		String systemDe = CryptoJava.de(systemsecret);
		if (StrUtil.isBlank(hostDe) || StrUtil.isBlank(systemDe)) {
			return;
		}
		long hostId = 0;
		long systemId = 0;
		if (NumberUtil.isNumber(hostDe)) {
			hostId = Long.valueOf(hostDe);
		}
		if (NumberUtil.isNumber(systemDe)) {
			systemId = Long.valueOf(systemDe);
		}
		if (hostId < 1 || systemId < 1) {
			return;
		}

		SSystem sSystem = systemServiceImpl.getInfoById(systemId);
		if (sSystem == null || sSystem.getHostId().longValue() != hostId) {
			return;
		}
		long siteId = sSystem.getSiteId();

		List<SInformationTitle> listSInformationTitle = informationServiceImpl.findSInformationTitleByHostSiteSystemId(hostId, siteId, systemId);
		if (CollUtil.isEmpty(listSInformationTitle)) {
			return;
		}
		List<SInformationTitle> collect = listSInformationTitle.stream().filter(item -> {
			return item.getType() != null && item.getType().shortValue() == (short) 1;
		}).collect(Collectors.toList());
		if (CollUtil.isEmpty(collect)) {
			return;
		}

		List<String> row1 = new ArrayList<>();
		collect.forEach(item -> {
			Short type = item.getType();
			if (type != null && type.shortValue() == (short) 1) {
				row1.add(item.getTitle());
			}
		});
		row1.add("");
		row1.add("（备注：系统根据前面的每一列的标题写入一行行的数据）");

		List<List<String>> rows = new ArrayList<>();
		rows.add(row1);

		// 下载
		try (ExcelWriter writer = ExcelUtil.getWriter(true); OutputStream out = response.getOutputStream();) {
			writer.renameSheet(0, sSystem.getName() + "属性字段");
			writer.setColumnWidth(row1.size() - 1, 56);
			writer.write(rows, true);

			String filename = sSystem.getName() + "-数据导入模板（" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm") + "）.xlsx";

//			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//			response.setHeader("Content-type", "text/html;charset=gbk");
			response.setHeader("Content-Transfer-Encoding", "binary");
			response.setContentType("application/x-download");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode(filename));

			writer.flush(out, true);
			writer.close();
			IoUtil.close(out);
		}
	}

	@GetMapping("/pdtable/excel-demo/{hostsecret}/{systemsecret}")
	public void pdtableExcelDemo(@PathVariable("hostsecret") String hostsecret, @PathVariable("systemsecret") String systemsecret, HttpServletResponse response)
			throws Exception {
		String hostDe = CryptoJava.de(hostsecret);
		String systemDe = CryptoJava.de(systemsecret);
		if (StrUtil.isBlank(hostDe) || StrUtil.isBlank(systemDe)) {
			return;
		}
		long hostId = 0;
		long systemId = 0;
		if (NumberUtil.isNumber(hostDe)) {
			hostId = Long.valueOf(hostDe);
		}
		if (NumberUtil.isNumber(systemDe)) {
			systemId = Long.valueOf(systemDe);
		}
		if (hostId < 1 || systemId < 1) {
			return;
		}

		SSystem sSystem = systemServiceImpl.getInfoById(systemId);
		if (sSystem == null || sSystem.getHostId().longValue() != hostId) {
			return;
		}
		long siteId = sSystem.getSiteId();

		List<SPdtableTitle> listSPdtableTitle = pdtableServiceImpl.findSPdtableTitleByHostSiteSystemId(hostId, siteId, systemId);
		if (CollUtil.isEmpty(listSPdtableTitle)) {
			return;
		}
		List<SPdtableTitle> collect = listSPdtableTitle.stream().filter(item -> {
			return item.getType() != null && item.getType().shortValue() == (short) 1;
		}).collect(Collectors.toList());
		if (CollUtil.isEmpty(collect)) {
			return;
		}

		List<String> row1 = new ArrayList<>();
		List<String> row2 = new ArrayList<>();
		List<String> row3 = new ArrayList<>();
		List<String> row4 = new ArrayList<>();

		row1.add("名称");
		row1.add("分类");
		row1.add("发布时间");

		row2.add("例子：Nexans");
		row2.add("例子：集成电路,连接器");
		row2.add("例子：" + DateUtil.format(DateUtil.date(), "yyyy/MM/dd HH:mm") + " 或 " + DateUtil.format(DateUtil.date(), "yyyy/MM/dd"));

		row3.add("");
		row3.add("");
		row3.add("");

		row4.add("");
		row4.add("");
		row4.add("");

		collect.forEach(item -> {
			Short type = item.getType();
			if (type != null && type.shortValue() == (short) 1) {
				row1.add(item.getTitle());
				row2.add("");
				row3.add("");
				row4.add("");
			}
		});

		row1.add("");
		row1.add("备注：前三列固定为系统固定字段，若变动后系统无法识别，便无法正常导入数据，如下列固定字段说明。");

		row2.add("");
		row2.add("名称：不能为空。");

		row3.add("");
		row3.add("分类：系统不存在的分类，会自动添加至系统顶级末尾，多个分类使用半角逗号【,】区分。例如：重金属,贵金属,....。");

		row4.add("");
		row4.add("发布时间：为空或者无法识别的日期时间，则为系统数据导入时间。");

		List<List<String>> rows = new ArrayList<>();
		rows.add(row1);
		rows.add(row2);
		rows.add(row3);
		rows.add(row4);

		// 下载
		try (ExcelWriter writer = ExcelUtil.getWriter(true); OutputStream out = response.getOutputStream();) {

			StyleSet styleSet = writer.getStyleSet();
			StyleUtil.setAlign(styleSet.getCellStyle(), HorizontalAlignment.LEFT, VerticalAlignment.CENTER);

			writer.renameSheet(0, sSystem.getName() + "属性字段");
			writer.setColumnWidth(0, 18);
			writer.setColumnWidth(1, 32);
			writer.setColumnWidth(2, 36);
			writer.setColumnWidth(row1.size() - 1, 120);
			writer.write(rows, true);

			String filename = sSystem.getName() + "-数据导入模板（" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm") + "）.xlsx";

//			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//			response.setHeader("Content-type", "text/html;charset=gbk");
			response.setHeader("Content-Transfer-Encoding", "binary");
			response.setContentType("application/x-download");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode(filename));

			writer.flush(out, true);
			writer.close();
			IoUtil.close(out);
		}
	}

}
